<?php
namespace lib\validation;


use Cross\Core\Helper;
use Cross\Core\FrameBase;
use lib\Crypts\TripleDES;

/**
 * @Auth: JH <hu@lunaz.cn>
 * Class Token
 * @package lib\validation
 */
class Token
{

    /**
     * 加解密key
     * @var string
     */
    private static $key = '^@#$&*^&-_@$&((^$#!!@#$*&^(!##@';
    /**
     * 严格模式，指定多个服务器host可使用的token
     * @var array
     */
    private static $aud = array();
    /**
     * @var string
     */
    private static $token = '';

    public static $msg = '无效TOKEN';


    /**
     * 设置加解密key
     *
     * @param string $key
     */
    static function setKey($key = '')
    {
        self::$key = $key;
    }

    /**
     * 设置服务器host可使用的token
     *
     * @param array $aud
     */
    static function setAud(array $aud = array())
    {
        if (!empty($aud)) {
            self::$aud = $aud;
        } else {
            self::$aud = array(self::getHost());
        }
    }

    /**
     * 获取host
     * @return mixed
     */
    private static function getHost()
    {
        return $_SERVER['HTTP_HOST'] != null ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'];
    }

    /**
     * 生成TOKEN
     *
     * @param null|string $controller
     * @param null|array $action
     *
     * @return mixed
     */
    static function buildToken($controller = null, $action = null)
    {
        $token = [];
        if ($controller) {
            $token['c'] = strtolower($controller);
        }
        if ($action) {
            if (!is_array($action)) {
                $action = array($action);
            }
            $token['a'] = array_map('strtolower', $action);
        }
        $token['ua'] = Helper::md10($_SERVER['HTTP_USER_AGENT']);
        $token['time'] = $_SERVER['REQUEST_TIME'];
        $token['aud'] = self::$aud;
        self::$token = json_encode($token);
        return self::authCode();
    }

    /**
     * 验证有效TOKEN
     *
     * @param int $expire 检验TOKEN有效时间（单位S）
     *
     * @return bool
     */
    static function validToken($expire = 0)
    {
        if (!self::$token = self::getParamToken()) {
            return false;
        }
        $token = json_decode(self::authCode(false), true);
        if (!$token) {
            return false;
        }
        if ($expire) {
            if (($_SERVER['REQUEST_TIME'] - $expire) > $token['time']) {
                return false;
            }
        }
        if (!empty($token['aud']) && !in_array(self::getHost(), $token['aud'])) {
            return false;
        }
        $app = FrameBase::$app_delegate->getApplication()->config->get('ori_router');
        if (!empty($token['c']) && $token['c'] != strtolower($app['controller'])) {
            return false;
        }
        $action = strtolower($app['action']);
        if (!empty($token['a']) && !in_array($action, $token['a'])) {
            return false;
        }
        return true;
    }

    /**
     * 转换URL加号（+）被编码成空格问题
     *
     * @param bool $encode
     *
     * @return mixed
     */
    private static function authCode($encode = true)
    {
        $td = new TripleDES(self::$key);
        if ($encode === true) {
            return $td->encrypt(self::$token);
        }
        return $td->decrypt(self::$token);
    }

    private static function getParamToken()
    {
        if (isset($_REQUEST['token'])) {
            return $_REQUEST['token'];
        } elseif (isset($_POST['token'])) {
            return $_POST['token'];
        } elseif (isset($_GET['token'])) {
            return $_GET['token'];
        } else {
            return false;
        }
    }
}